cmake_minimum_required(VERSION 3.10)

set(TARGET "liveStreamProxy")
project(${TARGET} VERSION 1.0)

if(NOT DEFINED CMAKE_SYSTEM_PROCESSOR)
    set(CMAKE_SYSTEM_PROCESSOR "x86")
    message(STATUS "CMAKE_SYSTEM_PROCESSOR not defined. Defaulting to x64.")
else()
    message(STATUS "Configuring for CMAKE_SYSTEM_PROCESSOR: ${CMAKE_SYSTEM_PROCESSOR}")
endif()

if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "x86" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "x64")
    set(PLATFORM "x86")
elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
    set(PLATFORM "aarch64")
else()
    message(FATAL_ERROR "Unsupported PLATFORM: ${PLATFORM}. Supported platforms are: x86, x64, x86_64, aarch64, arm64.")
endif()

set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CMAKE_COMMAND} -E time")
set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK "${CMAKE_COMMAND} -E time")

# 设置C++标准
set(C_STANDARD 11)
set(CMAKE_CXX_STANDARD 14)
set(POSITION_INDEPENDENT_CODE ON)
set(CMAKE_CXX_STANDARD_REQUIRED True)

# 设置构建类型
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
    set(CMAKE_C_FLAGS_DEBUG "$ENV{CFLAGS} -Wall -Wextra \
                            -Wno-unused-function \
                            -Wno-unused-result \
                            -O0 -g -fPIC \
                            -fstack-protector-all")

    set(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -Wextra -g -ggdb \
                              -Wno-unused-label -Wno-unused-variable \
                              -Wno-unused-function \
                              -Wno-unused-result \
                              -Wno-char-subscripts \
                              -fstack-protector-all")
    message(STATUS "CMAKE_BUILD_TYPE = Debug")
else()
    set(CMAKE_C_FLAGS_RELEASE "$ENV{CFLAGS} -Wall -Wextra \
                                -Wno-unused-function \
                                -Wno-unused-result \
                                -O3 -s -fPIC \
                                -fstack-protector-all")
                                
    set(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall -Wextra -fPIC \
                                -Wno-unused-label -Wno-unused-variable \
                                -Wno-unused-function \
                                -Wno-unused-result \
                                -Wno-char-subscripts \
                                -fstack-protector-all")
    message(STATUS "CMAKE_BUILD_TYPE = Release")
endif()

# 设置 ccache
find_program(CCACHE_PROGRAM ccache)
if(CCACHE_PROGRAM)
    message(STATUS "Set up ccache ...")
    set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)
    set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache)
endif()

# 使用 gold linker
if(UNIX AND NOT APPLE)
    set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fuse-ld=gold")
endif()

# 设置 CMAKE_PREFIX_PATH 以找到第三方库
list(APPEND CMAKE_PREFIX_PATH
    "${CMAKE_SOURCE_DIR}/3rdparty/${PLATFORM}/spdlog"
    "${CMAKE_SOURCE_DIR}/3rdparty/${PLATFORM}/ZLMediaKit"
    "${CMAKE_SOURCE_DIR}/3rdparty/${PLATFORM}/nlohmann"
)
if(PLATFORM STREQUAL "aarch64" OR PLATFORM STREQUAL "arm64")
    list(APPEND CMAKE_PREFIX_PATH
        "${CMAKE_SOURCE_DIR}/3rdparty/${PLATFORM}/openssl"
    )
endif()
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
find_package(Threads REQUIRED)
if(Threads_FOUND)
    message(STATUS "Threads library status:")
    message(STATUS "    version: ${Threads_VERSION}")
    message(STATUS "    libraries: ${Threads_LIBRARIES}")
    message(STATUS "    include path: ${THREADS_INCLUDE_DIR}")
else()
    message(FATAL_ERROR "Threads not found")
endif()

if(PLATFORM STREQUAL "x86" OR PLATFORM STREQUAL "x64")
    find_package(OpenSSL REQUIRED)
    if(OpenSSL_FOUND)
        message(STATUS "OpenSSL library status:")
        message(STATUS "    version: ${OPENSSL_VERSION}")
        message(STATUS "    libraries: ${OPENSSL_LIBRARIES}")
        message(STATUS "    include path: ${OPENSSL_INCLUDE_DIR}")
    else()
        message(FATAL_ERROR "OpenSSL not found")
    endif()
elseif(PLATFORM STREQUAL "aarch64" OR PLATFORM STREQUAL "arm64")
    set(OPENSSL_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/3rdparty/${PLATFORM}/openssl/include)
    set(OPENSSL_LIB_DIR ${CMAKE_SOURCE_DIR}/3rdparty/${PLATFORM}/openssl/lib)
    set(OPENSSL_LIBRARIES "${OPENSSL_LIB_DIR}/libssl.a"
                          "${OPENSSL_LIB_DIR}/libcrypto.a")
    message(STATUS "OpenSSL library status:")
    message(STATUS "    libraries: ${OPENSSL_LIBRARIES}")
    message(STATUS "    include path: ${OPENSSL_INCLUDE_DIR}")
    list(APPEND CMAKE_PREFIX_PATH
        "${CMAKE_SOURCE_DIR}/3rdparty/${PLATFORM}/fmt"
    )
    
    include_directories(
        /usr/aarch64-linux-gnu/include/
    )
    link_directories(
        /usr/aarch64-linux-gnu/lib/
    )
endif()

find_package(fmt REQUIRED)
if(fmt_FOUND)
    get_target_property(FMT_INCLUDE_DIRS fmt::fmt INTERFACE_INCLUDE_DIRECTORIES)
    message(STATUS "fmt library status:")
    message(STATUS "    version: ${fmt_VERSION}")
    message(STATUS "    include path: ${FMT_INCLUDE_DIRS}")
else()
    message(FATAL_ERROR "fmt not found")
endif()

# 显示 spdlog 状态
find_package(spdlog REQUIRED)
if(spdlog_FOUND)
    get_target_property(SPDLOG_INCLUDE_DIRS spdlog::spdlog INTERFACE_INCLUDE_DIRECTORIES)
    message(STATUS "spdlog library status:")
    message(STATUS "    version: ${spdlog_VERSION}")
    message(STATUS "    libraries: ${SPDLOG_LIBRARIES}")
    message(STATUS "    include path: ${SPDLOG_INCLUDE_DIRS}")
else()
    message(FATAL_ERROR "spdlog not found")
endif()

find_package(nlohmann_json REQUIRED)
if(nlohmann_json_FOUND)
    get_target_property(nlohmann_INCLUDE_DIRS nlohmann_json::nlohmann_json INTERFACE_INCLUDE_DIRECTORIES)
    message(STATUS "nlohmann_json library status:")
    message(STATUS "    version: ${nlohmann_json_VERSION}")
    message(STATUS "    include path: ${nlohmann_INCLUDE_DIRS}")
else()
    message(FATAL_ERROR "nlohmann_json not found")
endif()

# 添加 mk_api 库
set(MK_API_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/3rdparty/${PLATFORM}/ZLMediaKit/include)
set(MK_API_LIB_DIR ${CMAKE_SOURCE_DIR}/3rdparty/${PLATFORM}/ZLMediaKit/lib)
add_library(mk_api SHARED IMPORTED)
set_target_properties(mk_api PROPERTIES
    IMPORTED_LOCATION "${MK_API_LIB_DIR}/libmk_api.so"
)

SET(LIVE555_DIR ${CMAKE_SOURCE_DIR}/3rdparty/${PLATFORM}/live555)
set(LIVE555_LIBS
    ${LIVE555_DIR}/lib/libLiveRtspClient.a
    ${LIVE555_DIR}/lib/libliveMedia.a
    ${LIVE555_DIR}/lib/libBasicUsageEnvironment.a
    ${LIVE555_DIR}/lib/libgroupsock.a
    ${LIVE555_DIR}/lib/libUsageEnvironment.a
)
set(LIVE555_INCLUDE
    ${LIVE555_DIR}/include/liveRtspClient
    ${LIVE555_DIR}/include/groupsock
    ${LIVE555_DIR}/include/liveMedia
    ${LIVE555_DIR}/include/UsageEnvironment
    ${LIVE555_DIR}/include/BasicUsageEnvironment
)

set(VIDEO_PARSE_INCLUDE_DIR 
    ${CMAKE_SOURCE_DIR}/3rdparty/${PLATFORM}/videoParse/include
)
set(VIDEO_PARSE_LIBRARIES 
    ${CMAKE_SOURCE_DIR}/3rdparty/${PLATFORM}/videoParse/lib/libframeParse.a
)

include_directories(
    ${FMT_INCLUDE_DIRS}
    ${LIVE555_INCLUDE}
    ${MK_API_INCLUDE_DIR}
    ${SPDLOG_INCLUDE_DIRS}
    ${OPENSSL_INCLUDE_DIR}
    ${nlohmann_INCLUDE_DIRS}
    ${VIDEO_PARSE_INCLUDE_DIR}
    ${CMAKE_BINARY_DIR}/mongoose/include
)

# 添加 utils 子目录
add_subdirectory(3rdparty/mongoose)
add_subdirectory(src/utils)
add_subdirectory(src/config) 
add_subdirectory(src/streamproxy) 
add_subdirectory(src/httpservice) 
add_subdirectory(src/httpserver) 

# 添加可执行文件
aux_source_directory(${CMAKE_SOURCE_DIR}/src DIR_SRCS)
add_executable(${TARGET} ${DIR_SRCS})

# 添加依赖关系
add_dependencies(${TARGET} mongoose)

# 链接库
target_link_libraries(${TARGET} PRIVATE
    ${LIVE555_LIBS}
    ${VIDEO_PARSE_LIBRARIES}
    fmt::fmt
    dl
    pthread
    mongoose
    mk_api
    utils
    config
    streamproxy
    httpservice
    httpserver
    spdlog::spdlog
    ${OPENSSL_LIBRARIES}
)

# 设置包含目录
target_include_directories(${TARGET} PRIVATE
    ${CMAKE_SOURCE_DIR}/src
    ${CMAKE_SOURCE_DIR}/src/dto
    ${CMAKE_SOURCE_DIR}/src/utils/include
    ${CMAKE_SOURCE_DIR}/src/config/include
    ${CMAKE_SOURCE_DIR}/src/streamproxy/include
    ${CMAKE_SOURCE_DIR}/src/httpserver/include
    ${CMAKE_SOURCE_DIR}/src/httpservice/include
)

if(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "x86" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "x64")
    add_custom_command(
        TARGET ${TARGET} POST_BUILD
        COMMAND ${CMAKE_STRIP} --strip-unneeded ${TARGET}
        COMMENT "x86 build ${TARGET} successfully ..."
    )
elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
    add_custom_command(
        TARGET ${TARGET} POST_BUILD
        # COMMAND ${CMAKE_STRIP} --strip-unneeded ${TARGET}
        COMMENT "copy ${TARGET} to admin@192.168.116.142:/home/admin/work/liveStreamProxy/docker"
        # COMMAND scp -p ${TARGET} admin@192.168.116.142:/home/admin/work/liveStreamProxy/docker
    )
endif()
